/**
	Pulsar engine. Additional include file.
	Standard algorythms and useful functions.

	Copyright (C) 2013-2014 Dmitry Dolgov

	This program is free software; you can redistribute it and/or modify it under the terms of the
	GNU General Public License as published by the Free Software Foundation; either version 2 of
	the License, or (at your option) any later version.

	This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
	without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
	See the GNU General Public License for more details.
*/

namespace pl
{

#if defined(min)
#undef min
#endif // min
#if defined(max)
#undef max
#endif // max

/// Get min
template <class T> inline T min(T a, T b)
{
	return a < b ? a : b;
}

/// Get max
template <class T> inline T max(T a, T b)
{
	return a > b ? a : b;
}

/// Swap
template <class T> inline void swap(T& a, T& b)
{
	const T c = a;
	a = b;
	b = c;
	return;
}

/// Align value till nearest align
template <class T> inline void alignValue(T& offset, T align)
{
	if (align > 0 && ((offset % align) != 0))
	{
		offset += align - (offset % align);
	}
	return;
}

//
// Swap bytes in standard functions
//
inline void swapBytes(char& value) {}
inline void swapBytes(unsigned char& value) {}

inline void swapBytes(pl_uint16& value)
{
	value = ((value << 8) & 0xFF00) | ((value >> 8) & 0xFF);
	return;
}

inline void swapBytes(wchar_t& value)
{
	value = ((value << 8) & 0xFF00) | ((value >> 8) & 0xFF);
	return;
}

inline void swapBytes(pl_uint32& value)
{
	value = ((value & 0x000000FF) << 24) | ((value & 0x0000FF00) << 8) | ((value & 0x00FF0000) >> 8) | ((value & 0xFF000000) >> 24);
	return;
}

inline void swapBytes(pl_uint64& value)
{
	pl_uint32 hi = (pl_uint32)(value >> 32);
	pl_uint32 lo = (pl_uint32)(value);
	swapBytes(lo);
	swapBytes(hi);
	value = ((pl_uint64)lo << 32) | hi;
	return;
}

/*

inline void* swapBytes(void* i)
{
#ifdef PL_MSC
#pragma warning(push)
#pragma warning(disable: 4311)
#pragma warning(disable: 4312)
#endif
#if defined(PL_WINDOWS64)
	return reinterpret_cast<void*>(swapBytes(reinterpret_cast<pl_uint64>(i)));
#else
	return reinterpret_cast<void*>(swapBytes(reinterpret_cast<pl_uint32>(i)));
#endif
#ifdef PL_MSC
#pragma warning(pop)
#endif
}

inline void swapUints(pl_uint16* p, size_t count)
{
	for (size_t i = 0; i < count; ++i, ++p)
	{
		*p = swapBytes(*p);
	}
}

inline void swapUints(pl_uint32* p, size_t count)
{
	for (size_t i = 0; i < count; ++i, ++p)
	{
		*p = swapBytes(*p);
	}
}

inline void swapUints(pl_uint64* p, size_t count)
{
	for (size_t i = 0; i < count; ++i, ++p)
	{
		*p = swapBytes(*p);
	}
}
*/

} // namespace pl

//
// End of file 'pulsar_algorithm.h'
//
